#include "jsoncpp-1.9.5/include/json/json.h"
#include "http.hpp"
#include "task.hpp"
#include "my_redis.h"
#include "tool.h"

using namespace muduo;

const std::string root_path = "./wwwroot";

std::string RequestStr(const HttpRequest &req)
{
    std::stringstream ss;
    ss << req._method << " " << req._path << " " << req._version << "\r\n";
    for (auto it : req._params)
    {
        ss << it.first << ": " << it.second << "\r\n";
        DBG_LOG("RequestStr_params: first:%s ,second:%s", it.first, it.second);
    }

    for (auto it : req._headers)
    {
        ss << it.first << ": " << it.second << "\r\n";
        DBG_LOG("RequestStr_headers: first:%s ,second:%s", it.first.c_str(), it.second.c_str());
    }

    ss << "\r\n";
    ss << req._body;
    return ss.str();
}


void GetUserID(const HttpRequest &req, HttpResponse *rsp)
{   
    if (req._body.empty()) {
        std::cerr << "请求正文为空，无法解析 JSON" << std::endl;
        rsp->SetContent(R"({"error":"Request body is empty"})", "application/json");
        return;
    }

    Json::Value input_json;
    Json::CharReaderBuilder readerBuilder;
    std::string errs;

    // 解析 _body
    std::cout <<"req._method: " <<req._method <<std::endl;
    std::cout<<"req_path: "<<req._path<<std::endl;
    std::cout<<"req._body: "<<req._body <<std::endl;
    for(auto e : req._headers)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }

    for(auto e : req._params)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }

    std::istringstream s(req._body);
    if (!Json::parseFromStream(readerBuilder, s, &input_json, &errs)) {
        std::cerr << "JSON 解析失败: " << errs << std::endl;
        std::cerr << "请求正文: " << req._body << std::endl;
    }

    std::string clientIP = input_json["userIP"].asString();

    Json::Value response;

    std::string userID;
    
    userID = Task::getInstance()->GetUserID(clientIP);
    std::cout << "userID: "<<userID <<std::endl;
    if(userID=="")
    {
        response["status"] = "failed";

    }else{
        response["userID"] = userID;
    }

    
    
    Json::StreamWriterBuilder writer;
    writer["indentation"] = "    ";  
    
    std::string ret_json_string = Json::writeString(writer, response);

    std::cout << "JSON Response: " << ret_json_string << std::endl;

    rsp->SetContent(ret_json_string, "application/json");
}


void UploadDeckArchive(const HttpRequest &req, HttpResponse *rsp)
{
    if (req._body.empty()) {
        std::cerr << "请求正文为空，无法解析 JSON" << std::endl;
        rsp->SetContent(R"({"error":"Request body is empty"})", "application/json");
        return;
    }



    
    Json::Value input_json;
    Json::CharReaderBuilder readerBuilder;
    std::string errs;


    std::cout <<"req._method: " <<req._method <<std::endl;
    std::cout<<"req_path: "<<req._path<<std::endl;
    std::cout<<"req._body: "<<req._body <<std::endl;
    for(auto e : req._headers)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }
    for(auto e : req._params)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }
    std::istringstream s(req._body);
    if (!Json::parseFromStream(readerBuilder, s, &input_json, &errs)) {
        std::cerr << "JSON 解析失败: " << errs << std::endl;
        std::cerr << "请求正文: " << req._body << std::endl;
    }

    if(input_json["userID"] == "null" ||input_json["uploadTime"] =="null"  )
    {
        return;
    }

    if (!input_json.isMember("saveCardDatas") || input_json["saveCardDatas"].empty()) {
        std::cerr << "错误: saveCardDatas 字段缺失或为空" << std::endl;
        Json::Value ret_json;
        
    

        ret_json["status"] = "error";
        ret_json["code"] = 400;
        ret_json["message"] = "Field 'saveCardDatas' is required";
        
        Json::StreamWriterBuilder writer;
        writer["indentation"] = "    ";  
        std::string ret_json_string = Json::writeString(writer, ret_json);
        std::cout << "JSON Response: " << ret_json_string << std::endl;
        rsp->SetContent(ret_json_string, "application/json");
        return;
    }




    Json::Value ret_json;
    Task::getInstance()->UploadDeckArchive(input_json,&ret_json);

    Json::StreamWriterBuilder writer;
    writer["indentation"] = "    ";  
    std::string ret_json_string = Json::writeString(writer, ret_json);
    std::cout << "JSON Response: " << ret_json_string << std::endl;
    rsp->SetContent(ret_json_string, "application/json");
}

void DownloadOpponentArchive(const HttpRequest &req, HttpResponse *rsp)
{
    if (req._body.empty()) {
        std::cerr << "请求正文为空，无法解析 JSON" << std::endl;
        rsp->SetContent(R"({"error":"Request body is empty"})", "application/json");
        return;
    }

    Json::Value input_json;
    Json::CharReaderBuilder readerBuilder;
    std::string errs;
    
    std::cout <<"req._method: " <<req._method <<std::endl;
    std::cout<<"req_path: "<<req._path<<std::endl;
    std::cout<<"req._body: "<<req._body <<std::endl;
    for(auto e : req._headers)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }
    for(auto e : req._params)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }

    std::istringstream s(req._body);
    if (!Json::parseFromStream(readerBuilder, s, &input_json, &errs)) {
        std::cerr << "JSON 解析失败: " << errs << std::endl;
        std::cerr << "请求正文: " << req._body << std::endl;
    }

    Json::Value ret_json;
    Task::getInstance()->DownloadOpponentArchive(input_json,&ret_json);


    Json::StreamWriterBuilder writer;
    writer["indentation"] = "    ";  // 如果需要格式化，可以改成 `writer["indentation"] = "    ";`
    std::string ret_json_string = Json::writeString(writer, ret_json);
    std::cout << "JSON Response: " << ret_json_string << std::endl;
    rsp->SetContent(ret_json_string, "application/json");

}

void DownloadOpponentArchiveWithExtra(const HttpRequest &req, HttpResponse *rsp)
{
    if (req._body.empty()) {
        std::cerr << "请求正文为空，无法解析 JSON" << std::endl;
        rsp->SetContent(R"({"error":"Request body is empty"})", "application/json");
        return;
    }
    Json::Value input_json;
    Json::CharReaderBuilder readerBuilder;
    std::string errs;
    
    // 解析 _body
    std::cout <<"req._method: " <<req._method <<std::endl;
    std::cout<<"req_path: "<<req._path<<std::endl;
    std::cout<<"req._body: "<<req._body <<std::endl;
    for(auto e : req._headers)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }
    for(auto e : req._params)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }

    std::istringstream s(req._body);
    if (!Json::parseFromStream(readerBuilder, s, &input_json, &errs)) {
        std::cerr << "JSON 解析失败: " << errs << std::endl;
        std::cerr << "请求正文: " << req._body << std::endl;
    }

    Json::Value ret_json;
    Task::getInstance()->DownloadOpponentArchiveWithExtra(input_json,&ret_json);


    Json::StreamWriterBuilder writer;
    writer["indentation"] = "    ";  // 如果需要格式化，可以改成 `writer["indentation"] = "    ";`
    std::string ret_json_string = Json::writeString(writer, ret_json);
    std::cout << "JSON Response: " << ret_json_string << std::endl;
    rsp->SetContent(ret_json_string, "application/json");


}

void Login(const HttpRequest &req, HttpResponse *rsp)
{
    std::cout<<"test login"<<std::endl;

    const std::string word = req.GetParam("id"); // 获取名为word的参数值
    
    std::string ret_json_string;


    rsp->SetContent(ret_json_string, "application/json");
  
}

void PutFile(const HttpRequest &req, HttpResponse *rsp)
{
    rsp->SetContent(RequestStr(req), "text/plain");
}

void DelFile(const HttpRequest &req, HttpResponse *rsp)
{
    rsp->SetContent(RequestStr(req), "text/plain");
}


void test(const HttpRequest &req, HttpResponse *rsp)
{
    std::cout<<"===test==="<<std::endl;


    Json::Value response;
    

    response["test"] = true;
    
    // 使用 Json::StreamWriter 进行序列化
    Json::StreamWriterBuilder writer;
    writer["indentation"] = "    ";  // 如果需要格式化，可以改成 `writer["indentation"] = "    ";`
    
    std::string ret_json_string = Json::writeString(writer, response);

    std::cout << "JSON Response: " << ret_json_string << std::endl;



    rsp->SetContent(ret_json_string, "application/json");
  
}

void UploadOpponentData(const HttpRequest &req, HttpResponse *rsp)
{

    if (req._body.empty()) {
        std::cerr << "请求正文为空，无法解析 JSON" << std::endl;
        rsp->SetContent(R"({"error":"Request body is empty"})", "application/json");
        return;
    }

    
    Json::Value input_json;
    Json::CharReaderBuilder readerBuilder;
    std::string errs;


    // 解析 _body
    std::cout <<"req._method: " <<req._method <<std::endl;
    std::cout<<"req_path: "<<req._path<<std::endl;
    std::cout<<"req._body: "<<req._body <<std::endl;
    for(auto e : req._headers)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }
    for(auto e : req._params)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }
    std::istringstream s(req._body);
    if (!Json::parseFromStream(readerBuilder, s, &input_json, &errs)) {
        std::cerr << "JSON 解析失败: " << errs << std::endl;
        std::cerr << "请求正文: " << req._body << std::endl;
    }

    Json::Value ret_json;
    Task::getInstance()->UploadOpponentData(input_json,&ret_json);

    Json::StreamWriterBuilder writer;
    writer["indentation"] = "    ";  // 如果需要格式化，可以改成 `writer["indentation"] = "    ";`
    std::string ret_json_string = Json::writeString(writer, ret_json);
    std::cout << "JSON Response: " << ret_json_string << std::endl;
    rsp->SetContent(ret_json_string, "application/json");
}





void MatchOpponent(const HttpRequest& req, HttpResponse* rsp) {
    if (req._body.empty()) {
        std::cerr << "请求正文为空，无法解析 JSON" << std::endl;
        rsp->SetContent(R"({"error":"Request body is empty"})", "application/json");
        return;
    }

    
    Json::Value input_json;
    Json::CharReaderBuilder readerBuilder;
    std::string errs;


    // 解析 _body
    std::cout <<"req._method: " <<req._method <<std::endl;
    std::cout<<"req_path: "<<req._path<<std::endl;
    std::cout<<"req._body: "<<req._body <<std::endl;
    for(auto e : req._headers)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }
    for(auto e : req._params)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }
    std::istringstream s(req._body);
    if (!Json::parseFromStream(readerBuilder, s, &input_json, &errs)) {
        std::cerr << "JSON 解析失败: " << errs << std::endl;
        std::cerr << "请求正文: " << req._body << std::endl;
    }

 
    

    // 从请求中获取用户信息
    string userID = input_json["userID"].asString();
    string uploadTime = input_json["uploadTime"].asString();
    int level = input_json["level"].asInt();

    Rank rank = static_cast<Rank>(level);
    int totalSession = input_json["totalSession"].asInt();
    int winSession =input_json["winSession"].asInt();

    BattleRecord userRecord{userID, uploadTime, rank, totalSession, winSession};

    sw::redis::Redis redis("tcp://127.0.0.1:6379");

    auto match = findMatch(redis, userRecord, 5);  // 5秒超时

    Json::Value ret_json;  // 创建 JSON 对象

    if (match) {
        Json::Value Opponent_json;
        opponentToJson(Opponent_json,*match);
        Task::getInstance()->DownloadOpponentArchive(Opponent_json,&ret_json);

    } else {
        // 未匹配到对手，返回失败信息
        ret_json["matchFound"] = false;
        ret_json["message"] = "No opponent found.";
    }

    Json::StreamWriterBuilder writer;
    writer["indentation"] = "    ";  // 如果需要格式化输出，可以改为 "    "
    std::string ret_json_string = Json::writeString(writer, ret_json);
    
    // 输出 JSON 响应
    std::cout << "JSON Response: " << ret_json_string << std::endl;
    
    // 设置 HTTP 响应内容
    rsp->SetContent(ret_json_string, "application/json");
}

void DownloadOpponentArchiveInRankMode(const HttpRequest& req, HttpResponse* rsp)
{
    if (req._body.empty()) {
        std::cerr << "请求正文为空，无法解析 JSON" << std::endl;
        rsp->SetContent(R"({"error":"Request body is empty"})", "application/json");
        return;
    }

    
    Json::Value input_json;
    Json::CharReaderBuilder readerBuilder;
    std::string errs;


    // 解析 _body
    std::cout <<"req._method: " <<req._method <<std::endl;
    std::cout<<"req_path: "<<req._path<<std::endl;
    std::cout<<"req._body: "<<req._body <<std::endl;
    for(auto e : req._headers)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }
    for(auto e : req._params)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }
    std::istringstream s(req._body);
    if (!Json::parseFromStream(readerBuilder, s, &input_json, &errs)) {
        std::cerr << "JSON 解析失败: " << errs << std::endl;
        std::cerr << "请求正文: " << req._body << std::endl;
    }

 
    

    // 从请求中获取用户信息
    string userID = input_json["userID"].asString();
    string uploadTime = input_json["uploadTime"].asString();
    int level = input_json["level"].asInt();

    Rank rank = static_cast<Rank>(level);
    int totalSession = input_json["totalSession"].asInt();
    int winSession =input_json["winSession"].asInt();

    BattleRecord userRecord{userID, uploadTime, rank, totalSession, winSession};

    sw::redis::Redis redis("tcp://127.0.0.1:6379");

    auto match = randFindMatch(redis, userRecord, 5);  // 5秒超时

    Json::Value ret_json;  // 创建 JSON 对象

    if (match) {
        Json::Value Opponent_json;
        opponentToJson(Opponent_json,*match);
        Task::getInstance()->DownloadOpponentArchive(Opponent_json,&ret_json);

    } else {
        // 未匹配到对手，返回失败信息
        ret_json["matchFound"] = false;
        ret_json["message"] = "No opponent found.";
    }

    Json::StreamWriterBuilder writer;
    writer["indentation"] = "    ";  // 如果需要格式化输出，可以改为 "    "
    std::string ret_json_string = Json::writeString(writer, ret_json);
    
    // 输出 JSON 响应
    std::cout << "JSON Response: " << ret_json_string << std::endl;
    
    // 设置 HTTP 响应内容
    rsp->SetContent(ret_json_string, "application/json");



}


void MatchOpponentWithExtra(const HttpRequest& req, HttpResponse* rsp) {
    if (req._body.empty()) {
        std::cerr << "请求正文为空，无法解析 JSON" << std::endl;
        rsp->SetContent(R"({"error":"Request body is empty"})", "application/json");
        return;
    }

    
    Json::Value input_json;
    Json::CharReaderBuilder readerBuilder;
    std::string errs;


    // 解析 _body
    std::cout <<"req._method: " <<req._method <<std::endl;
    std::cout<<"req_path: "<<req._path<<std::endl;
    std::cout<<"req._body: "<<req._body <<std::endl;
    for(auto e : req._headers)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }
    for(auto e : req._params)
    {
        std::cout<< e.first <<" "<<e.second <<std::endl;
    }
    std::istringstream s(req._body);
    if (!Json::parseFromStream(readerBuilder, s, &input_json, &errs)) {
        std::cerr << "JSON 解析失败: " << errs << std::endl;
        std::cerr << "请求正文: " << req._body << std::endl;
    }

 
    

    // 从请求中获取用户信息
    string userID = input_json["userID"].asString();
    string uploadTime = input_json["uploadTime"].asString();
    int level = input_json["level"].asInt();

    Rank rank = static_cast<Rank>(level);
    int totalSession = input_json["totalSession"].asInt();
    int winSession =input_json["winSession"].asInt();

    BattleRecord userRecord{userID, uploadTime, rank, totalSession, winSession};

    // sw::redis::Redis redis("tcp://127.0.0.1:6379");

    //auto match = findMatch(redis, userRecord, 5);  // 5秒超时
    auto match = findMatchFromMySQLWithExtra(userRecord);
    Json::Value ret_json;  // 创建 JSON 对象

    if (match) {
        Json::Value Opponent_json;
        opponentToJson(Opponent_json,*match);
        Task::getInstance()->DownloadOpponentArchiveWithExtra(Opponent_json,&ret_json);

    } else {
        // 未匹配到对手，返回失败信息
        ret_json["matchFound"] = false;
        ret_json["message"] = "No opponent found.";
    }

    Json::StreamWriterBuilder writer;
    writer["indentation"] = "    ";  // 如果需要格式化输出，可以改为 "    "
    std::string ret_json_string = Json::writeString(writer, ret_json);
    
    // 输出 JSON 响应
    std::cout << "JSON Response: " << ret_json_string << std::endl;
    
    // 设置 HTTP 响应内容
    rsp->SetContent(ret_json_string, "application/json");
}



// int main()       
// {
//     HttpServer server(8085);
//     server.SetThreadCount(10);
//     server.SetBaseDir(root_path); 
//     server.Get("/test", test);
//     server.Post("/GetUserID", GetUserID);
//     server.Post("/UploadDeckArchive",UploadDeckArchive);
//     server.Post("/DownloadOpponentArchive",DownloadOpponentArchive);
//     server.Post("/UploadOpponentData",UploadOpponentData);
//     server.Post("/MatchOpponent", MatchOpponent);
//     server.Post("/DownloadOpponentArchiveInRankMode",DownloadOpponentArchiveInRankMode);
//     server.Post("/MatchOpponentWithExtra", MatchOpponentWithExtra);
    

//     server.Post("/login", Login);
//     server.Put("/1234.txt", PutFile);
//     server.Delete("/1234.txt", DelFile);
//     server.Listen();
//     return 0;
// }




int main()       
{


    DBConnectionPool::getInstance()->initialize("localhost", "root", "819101", "card_game", 3306);
    HttpServer server(8085,"card_game");
    server.SetThreadCount(10);
    server.SetBaseDir(root_path); 
    server.Get("/test", test);
    server.Post("/GetUserID", GetUserID);
    server.Post("/UploadDeckArchive",UploadDeckArchive);
    server.Post("/DownloadOpponentArchive",DownloadOpponentArchive);
    server.Post("/UploadOpponentData",UploadOpponentData);
    server.Post("/MatchOpponent", MatchOpponent);
    server.Post("/DownloadOpponentArchiveInRankMode",DownloadOpponentArchiveInRankMode);
    server.Post("/MatchOpponentWithExtra", MatchOpponentWithExtra);
    

    server.Post("/login", Login);
    server.Put("/1234.txt", PutFile);
    server.Delete("/1234.txt", DelFile);
    server.Listen();
    return 0;
}
